﻿using LiteDB;
using Newtonsoft.Json;
using System.Text;

namespace Simple.Utils
{
    /// <summary>APP数据字典帮助类，存储在LiteDB中 类似于字典 db -&gt; table -&gt; (k,v)</summary>
    internal class ApplicationConfig
    {
        public int Id { get; set; }
        public string Key { get; set; }
        public byte[] Value { get; set; }
    }

    /// <summary>LitDb下的一个配置管理 APP数据字典帮助类，存储在LiteDB中 类似于字典 db -&gt; table -&gt; (k,v)</summary>
    public class AppProfileDataDb : IDisposable
    {
        private static readonly Lazy<AppProfileDataDb> _instance =
            new Lazy<AppProfileDataDb>(() => new AppProfileDataDb("profile"));

        private LiteDatabase _profileDb;

        private AppProfileDataDb(string dbName)
        {
            _profileDb = new LiteDatabase($"{dbName}.db");
            // 确保 TempData 表的索引
            TempData.EnsureIndex();
        }

        internal LiteDatabase ProfileDb => _profileDb;

        /// <summary>临时数据的存储表 默认表名称TempData</summary>
        public AppProfileDataTable TempData => new AppProfileDataTable(this, "TempData");

        /// <summary>获取实例</summary>
        /// <returns></returns>
        public static AppProfileDataDb GetInstance(string dbName = "")
        {
            if (!string.IsNullOrEmpty(dbName))
            {
                return new AppProfileDataDb(dbName);
            }
            return _instance.Value;
        }

        public void Dispose()
        {
            _profileDb?.Dispose();
        }
    }

    /// <summary>程序数据字典表 注意内部Key不要重复</summary>
    public class AppProfileDataTable
    {
        private readonly ILiteCollection<ApplicationConfig> _collection;

        internal AppProfileDataTable(AppProfileDataDb appDb, string collectionName)
        {
            _collection = appDb.ProfileDb.GetCollection<ApplicationConfig>(collectionName);
        }

        /// <summary>确保索引存在</summary>
        public void EnsureIndex()
        {
            _collection.EnsureIndex(x => x.Key);
        }

        /// <summary>设置表字段数据</summary>
        /// <param name="key">字段名称</param>
        /// <param name="value">字段值</param>
        public void Set(string key, object value)
        {
            var json = JsonConvert.SerializeObject(value);
            var buff = Encoding.UTF8.GetBytes(json);

            var kv = _collection.FindOne(x => x.Key == key) ?? new ApplicationConfig { Key = key };

            kv.Value = buff;

            _collection.Upsert(kv);
        }

        /// <summary>获取字典key值</summary>
        /// <typeparam name="T">期望返回的类型</typeparam>
        /// <param name="key">字典key</param>
        /// <returns></returns>
        public T? Get<T>(string key)
        {
            var kv = _collection.FindOne(x => x.Key == key);
            if (kv == null)
            {
                return default;
            }

            try
            {
                return JsonConvert.DeserializeObject<T>(Encoding.UTF8.GetString(kv.Value));
            }
            catch (JsonException ex)
            {
                // 记录异常或处理
                Console.WriteLine($"Deserialization error: {ex.Message}");
                return default;
            }
        }
    }
}